//
//  YHDelayPerformer.swift
//  YHKit
//
//  Created by amovision on 2025/9/13.
//

import Foundation

public class DelayPerformer {
  // 静态常量，提供全局访问点
  public static let shared = DelayPerformer()

  // 线程安全的字典，用于存储 DispatchWorkItem
  private var tasks: [AnyHashable: DispatchWorkItem] = [:]
  // 使用并发队列和栅栏来保证字典操作的线程安全
  private let queue = DispatchQueue(label: "com.amv.adorbee.delay.queue", attributes: .concurrent)

  /// 延迟执行一个任务，并用唯一的标识符绑定
  /// - Parameters:
  ///   - identifier: 唯一的任务标识符 (Hashable)
  ///   - delay: 延迟的秒数
  ///   - block: 要执行的代码块
  public func perform(withIdentifier identifier: AnyHashable, delay: TimeInterval, block: @escaping () -> Void) {
    // 在执行新任务前，先取消旧任务，防止任务冲突
    self.cancel(withIdentifier: identifier)

    let workItem = DispatchWorkItem { [weak self] in
      block()
      self?.queue.async(flags: .barrier) {
        self?.tasks.removeValue(forKey: identifier)
      }
    }

    self.queue.async(flags: .barrier) {
      self.tasks[identifier] = workItem
    }

    DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: workItem)
  }

  /// 取消一个指定标识符的任务
  /// - Parameter identifier: 唯一的任务标识符
  public func cancel(withIdentifier identifier: AnyHashable) {
    // 确保取消和移除操作是线程安全的
    self.queue.async(flags: .barrier) {
      if let workItem = self.tasks[identifier] {
        if !workItem.isCancelled {
          workItem.cancel()
        }
        self.tasks.removeValue(forKey: identifier)
      }
    }
  }
}
